package net.sf.calibur.ai.pathfinder;

import java.util.Collection;

import net.sf.calibur.util.BinaryHeap;

/**
 * 用二叉堆实现的开放节点队列。
 * 
 * @author gaobo.benny
 * 
 */
public class BinaryHeapOpenList implements OpenList {
	private BinaryHeap<AStarNode> queue;

	public BinaryHeapOpenList() {
		queue = new BinaryHeap<AStarNode>(128);
	}

	@Override
	public void clear() {
		queue.clear();
	}

	@Override
	public int size() {
		return queue.size();
	}

	@Override
	public Collection<AStarNode> values() {
		return queue;
	}

	@Override
	public void add(AStarNode node) {
		if (node == null) {
			throw new IllegalArgumentException();
		} else if (get(node.getX(), node.getY()) != null) {
			return;
		}

		queue.add(node);
	}

	@Override
	public void touchNeighbor(AStarNode neighbor, AStarNode current,
			AStarNode target) {
		int index = queue.indexOf(neighbor);
		if (index < 0) {
			neighbor.calculatorF(current, target);
			add(neighbor);
		} else {
			AStarNode node = queue.getAt(index);
			if (node.getDistinctG(current) < node.getG()) {
				int oldF = node.getF();
				int newF = node.calculatorF(current, target);
				if (oldF != newF) {
					queue.modifiedAt(index);
				}
			}
		}
	}

	@Override
	public AStarNode get(int x, int y) {
		for (AStarNode node : queue) {
			if (node.getX() == x && node.getY() == y) {
				return node;
			}
		}

		return null;
	}

	@Override
	public AStarNode poll() {
		return queue.poll();
	}
}
